package com.countertack.endtoendstories;

import java.io.File;
import java.io.FileOutputStream;
import java.net.InetAddress;
import java.sql.ResultSet;
import java.util.UUID;

import org.json.JSONObject;

import com.countertack.impala.ImpalaConnector;
import com.countertack.ssh.SSHManager;
import com.countertack.utils.Configuration;
import com.countertack.utils.HttpClientUtils;
import com.countertack.vmware.VMWareConnector;
import com.countertack.vmware.VMWareUtils;
import com.vmware.vim25.mo.VirtualMachine;

public class EndToEndProfilesAndGroups {
	public static void main(String[] args) throws Exception {

//		if (args.length <= 0) {
//
//			System.out.println("configuration details missed !");
//			return;
//		}
//		String configFilePath = args[0];
		String configFilePath="C:\\Users\\user\\Desktop\\endtoendautomation\\config.properties";

		// String configFilePath =
		// "C:\\Users\\user\\Desktop\\configm.properties";

		Configuration.loadProperties(configFilePath);
		String vmUser = Configuration.getProperty("vmuser");
		String vmPassword = Configuration.getProperty("vmpassword");
		StringBuffer testCaseResult = new StringBuffer();
		String uuid = UUID.randomUUID().toString();
		Configuration.loadProperties(configFilePath);

		ImpalaConnector iConnector;

		iConnector = ImpalaConnector
				.createImpalaConnectorInstance(Configuration
						.getProperty("sentinelehost"));

		InetAddress address = InetAddress.getByName(Configuration
				.getProperty("sentinelehost"));
		String sentenelIp = address.getHostAddress();
		System.out.println(address.getHostAddress());
		// connect to esxi and starting virtual machines

		// starting endpoint machine

		VMWareConnector esxiConnector = new VMWareConnector(
				Configuration.getProperty("esxi"));
		// poweredOn
		final VirtualMachine endPointMachine = esxiConnector
				.getVirtualMachineByname(Configuration.getProperty("vmname"));

		System.out.println("power state >>>"
				+ endPointMachine.getRuntime().powerState);

		String endpointMachineStatus = esxiConnector
				.getVirtualMachineStatus(endPointMachine);

		if (endpointMachineStatus == null) {

			System.out.println("Power on  endpoint machine .....");

			esxiConnector.startVirtualMachine(endPointMachine);

			Thread.sleep(600000);

		} else {

			if ("notRunning".equalsIgnoreCase(endpointMachineStatus)) {

				esxiConnector.reStartVirtualMachine(endPointMachine);

				System.out.println("Rebooting endpoint machine .....");

				Thread.sleep(600000);

			}

		}
		
		
		String smokeSnapShotName = Configuration
				.getProperty("rootsnapshotname");
		esxiConnector.revertToSnapShort(endPointMachine.getSnapshot()
				.getRootSnapshotList(), smokeSnapShotName);

		System.out.println("Reverting to root snap shot>>>>>"
				+ smokeSnapShotName);

		Thread.sleep(180000);

		endpointMachineStatus = esxiConnector
				.getVirtualMachineStatus(endPointMachine);

		if (endpointMachineStatus == null) {

			System.out.println("Power on  endpoint machine .....");

			esxiConnector.startVirtualMachine(endPointMachine);

			Thread.sleep(600000);

		} else {

			if ("notRunning".equalsIgnoreCase(endpointMachineStatus)) {

				esxiConnector.reStartVirtualMachine(endPointMachine);

				System.out.println("Rebooting endpoint machine .....");

				Thread.sleep(600000);

			}

		}
		
		

		String smartGroupFilterneme = "WIN7";

		if (endPointMachine.getGuest().hostName != null) {

			smartGroupFilterneme = endPointMachine.getGuest().hostName
					.toUpperCase();

			if (smartGroupFilterneme.length() > 10) {

				smartGroupFilterneme = smartGroupFilterneme.substring(0, 10);

			}

			System.out.println("Fileter name>>>" + smartGroupFilterneme);

		}

		// Creating Manual Group

		String manualRootPayload = "{\"name\":\"Manual Root\",\"rule\":{\"type\":\"manual\"}}";

		String manualRootRes = HttpClientUtils.composePostRequest("https://"
				+ Configuration.getProperty("sentinelehost")
				+ ":9090/api/v1/groups", manualRootPayload);

		System.out.println("manual root  response>>>" + manualRootRes);
		testCaseResult
				.append("manual root  response>>>" + manualRootRes + "\n");

		JSONObject mrObj = new JSONObject(manualRootRes);

		String mrootgrpId = mrObj.optString("id");

		if (mrootgrpId == null || mrootgrpId.trim() == "") {

			System.out
					.println("Creation of  manual root group------------->Fail");
			testCaseResult
					.append("Creation of  manual root group------------->Fail \n");

		} else {

			System.out
					.println("Creation of  manual root group------------->Pass");
			testCaseResult
					.append("Creation of  manual root group------------->Pass \n");

		}

		String manualLeafPayload = "{\"name\":\"Manual Leaf\",\"parent\":\""
				+ mrootgrpId + "\",\"rule\":{\"type\":\"manual\"}}";
		String manualLeafRes = HttpClientUtils.composePostRequest("https://"
				+ Configuration.getProperty("sentinelehost")
				+ ":9090/api/v1/groups", manualLeafPayload);

		System.out.println("manual leaf response>>>" + manualLeafRes);
		testCaseResult.append("manual leaf response>>>" + manualLeafRes + "\n");
		JSONObject mlObj = new JSONObject(manualLeafRes);

		String mleafgrpId = mlObj.optString("id");

		if (mleafgrpId == null || mleafgrpId.trim() == "") {

			// System.out.println("Creation of  manual leaf group----->Fail");

		}

		else {

			// System.out.println("Creation of  manual leaf group----->Pass");
		}

		String manLeafGetRes = HttpClientUtils.get("https://"
				+ Configuration.getProperty("sentinelehost")
				+ ":9090/api/v1/groups/" + mleafgrpId);

		JSONObject mlgetObj = new JSONObject(manLeafGetRes);

		String mleafgrpParent = mlgetObj.optString("parent");

		if (!mrootgrpId.equalsIgnoreCase(mleafgrpParent)) {

			System.out.println("Creation of  manual leaf group----->Fail");
			testCaseResult
					.append("Creation of  manual leaf group----->Fail \n");

		} else {

			System.out.println("Creation of  manual leaf group----->Pass");
			testCaseResult
					.append("Creation of  manual leaf group----->Pass \n");
		}

		// creting smart group with endpoint name filter

		String smartRootPayload = "{\"name\":\"Smart Root\",\"rule\":{\"type\":\"manual\"}}";

		String smartRootRes = HttpClientUtils.composePostRequest("https://"
				+ Configuration.getProperty("sentinelehost")
				+ ":9090/api/v1/groups", smartRootPayload);

		JSONObject srObj = new JSONObject(smartRootRes);

		String srootgrpId = srObj.optString("id");

		if (srootgrpId == null || srootgrpId.trim() == "") {

			// System.out.println("Creation of  smart root group----------->Pass");
			// System.exit(0);

		}

		String putPayload = "{\"title\":\"Smart Root\",\"key\":\""
				+ srootgrpId
				+ "\",\"isFolder\":false,\"isLazy\":false,\"addClass\":\"group-item group-item-manual\",\"noLink\":false,\"activate\":false,\"focus\":false,\"expand\":true,\"select\":false,\"hideCheckbox\":false,\"unselectable\":false,\"children\":[],\"id\":\""
				+ srootgrpId
				+ "\",\"name\":\"Smart Root\",\"rule\":{\"type\":\"smart\",\"value\":{\"term\":{\"type\":\"and\",\"args\":[{\"type\":\"contains\",\"field\":{\"type\":\"variable\",\"table\":\"endpoints\",\"name\":\"name\"},\"val\":{\"type\":\"string\",\"value\":\""
				+ smartGroupFilterneme
				+ "\"}}]}},\"notes\":{\"filters\":\"[{\\\"type\\\":\\\"string\\\",\\\"field\\\":\\\"name\\\",\\\"operator\\\":\\\"contains\\\",\\\"value\\\":\\\""
				+ smartGroupFilterneme
				+ "\\\",\\\"group\\\":{\\\"name\\\":\\\"Endpoint\\\",\\\"type\\\":\\\"group\\\"}}]\"}}}";

		HttpClientUtils.composePutRequest(
				"https://" + Configuration.getProperty("sentinelehost")
						+ ":9090/api/v1/groups/" + srootgrpId, putPayload);

		String srootgt = HttpClientUtils.get("https://"
				+ Configuration.getProperty("sentinelehost")
				+ ":9090/api/v1/groups/" + srootgrpId);

		if (srootgt.contains(smartGroupFilterneme)) {

			System.out.println("Creation of  smart root group----------->Pass");
			testCaseResult
					.append("Creation of  smart root group----------->Pass \n");

		} else {

			System.out.println("Creation of  smart root group----------->Fail");
			testCaseResult
					.append("Creation of  smart root group----------->Fail \n");

		}
		
		
		boolean isXpmachine=false;
		
		String osType = VMWareUtils.getVMOSArchitecture(
				Configuration.getProperty("esxi"),
				Configuration.getProperty("vmname"));
		testCaseResult.append("OS>>>>" + osType + "\n");
		if (osType != null) {

			osType = osType.toLowerCase();

			if (osType.contains("xp")) {

				isXpmachine = true;
			}
		}

		// installing agent on endpoint

		// initialising ssh to virtual machines

		System.out.println("ip>>>" + endPointMachine.getGuest().ipAddress);

		final SSHManager endpointSsh = new SSHManager(vmUser, vmPassword,
				endPointMachine.getGuest().ipAddress);
		endpointSsh.connect();

		// install agent

		endpointSsh.copyFile(Configuration.getProperty("driverpath"),
				"CounterTack Agent Installer Hiding.exe");

		if (isXpmachine) {
			endpointSsh
					.runCommand("cmd /c \"C:\\Documents and Settings\\"
							+ vmUser
							+ "\\CounterTack Agent Installer Hiding.exe\" /S /HOST:"
							+ sentenelIp + " /PORT:443");

		} else {

			endpointSsh
					.runCommand("cmd /c \"C:\\Users\\"
							+ vmUser
							+ "\\CounterTack Agent Installer Hiding.exe\" /S /HOST:"
							+ sentenelIp + " /PORT:443");

		}

		System.out.println("Installing agent on endpoint");
		Thread.sleep(120000);

		String eId = null;
		ResultSet endpointIdRes = iConnector
				.executeQueryAndReturnResults("select id from endpoints where ip='"
						+ endPointMachine.getGuest().ipAddress
						+ "'"
						+ " and status='ON'and ip is not null  order by time_started desc limit 1");

		while (endpointIdRes.next()) {
			try {
				eId = endpointIdRes.getString(1);
			} catch (Exception e) {

			}

			System.out.println("endpoint Id>>>>>>" + eId);
			testCaseResult.append("endpoint Id>>>>>>" + eId + "\n");

		}

		if (eId == null) {

			System.out.println("endpoint is not installed");
			testCaseResult.append("endpoint is not installed \n");
			addResultsToLog(testCaseResult);
			System.exit(0);

		} else {

			System.out.println("Endpoint installed success fully");
			testCaseResult.append("Endpoint installed success fully \n");
		}

		System.out.println("Pausing Endpoint...");
		pauseEndpoint(eId);
		Thread.sleep(60000);

		System.out.println("Resuming Endpoint...");
		resumeEndpoint(eId);
		Thread.sleep(60000);

		// verifying smart groups
		ResultSet smartGroupEndpoints = iConnector
				.executeQueryAndReturnResults("select endpoints from groups where id='"
						+ srootgrpId + "'");
		boolean isSmartGroupWorks = false;

		while (smartGroupEndpoints.next()) {
			String endpoints = smartGroupEndpoints.getString(1);

			if (endpoints != null) {

				System.out.println("smart group endpoints>>>" + endpoints);
				testCaseResult.append("smart group endpoints>>>" + endpoints
						+ "\n");
				if (endpoints.contains(eId)) {

					// System.out.println("Inbound passed");
					isSmartGroupWorks = true;
					break;
					// System.exit(0);
					// return;

				}

			}
		}

		if (isSmartGroupWorks) {
			System.out.println("Verifying smart group-------->Pass");
			testCaseResult.append("Verifying smart group-------->Pass \n");
		} else {

			System.out.println("Verifying smart group-------->Fail");
			testCaseResult.append("Verifying smart group-------->Fail \n");
		}

		// add endpoint to manual group

		String payloadAddendPntToGroup = "{\"type\": \"add_endpoints_to_group\",\"endpoints\":[\""
				+ eId + "\"]}";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi") + "/groups/"
						+ mrootgrpId + "/command", payloadAddendPntToGroup);

		Thread.sleep(60000);

		// verifying manual group

		ResultSet manualgrpEndpoints = iConnector
				.executeQueryAndReturnResults("select endpoints from groups where id='"
						+ mrootgrpId + "'");
		boolean ismanualGroupWorks = false;

		while (manualgrpEndpoints.next()) {
			String endpoints = manualgrpEndpoints.getString(1);

			if (endpoints != null) {

				System.out.println("manual group endpoints>>>" + endpoints);
				testCaseResult.append("manual group endpoints>>>" + endpoints
						+ "\n");
				if (endpoints.contains(eId)) {

					// System.out.println("Inbound passed");
					ismanualGroupWorks = true;
					break;
					// System.exit(0);
					// return;

				}

			}
		}

		if (ismanualGroupWorks) {
			System.out.println("Verifying manual group-------->Pass");
			testCaseResult.append("Verifying manual group-------->Pass \n");
		} else {

			System.out.println("Verifying manual group-------->Fail");
			testCaseResult.append("Verifying manual group-------->Fail \n");
		}

		// applying profile to endpoint

		String profilePayload = "{ "
				+ "  \"type\": \"apply_profile_to_endpoints\", "
				+ "  \"profile\":\"" + Configuration.getProperty("profilename")
				+ "\", " + "  \"endpoints\":[ " + "\"" + eId + "\" " + "] "
				+ "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", profilePayload);

		Thread.sleep(3000);

		pauseEndpoint(eId);
		System.out.println("Pausing endpoint");
		Thread.sleep(60000);

		resumeEndpoint(eId);
		System.out.println("Resuming endpoint");
		Thread.sleep(60000);

		// verifying profile

		ResultSet currentProfileRset = iConnector
				.executeQueryAndReturnResults("select cp from endpoints where id='"
						+ eId + "'");
		boolean isProfilechanged = false;

		while (currentProfileRset.next()) {
			String currentProfile = currentProfileRset.getString(1);

			if (currentProfile != null) {

				System.out.println("Current Profile>>>" + currentProfile);
				if (currentProfile.contains(Configuration
						.getProperty("profilename"))) {

					// System.out.println("Inbound passed");
					isProfilechanged = true;
					break;
					// System.exit(0);
					// return;

				}

			}
		}

		if (isProfilechanged) {
			System.out.println("Changing Profile-------->Pass");
			testCaseResult.append("Changing Profile-------->Pass \n");

			System.out.println("Verifying Profile updation-------->Pass");
			testCaseResult.append("Verifying Profile updation-------->Pass \n");
		} else {

			System.out.println("Changing Profile-------->Fail");
			testCaseResult.append("Changing Profile-------->Fail \n");

			System.out.println("Verifying Profile updation-------->Fail");
			testCaseResult.append("Verifying Profile updation-------->Fail \n");
		}
		addResultsToLog(testCaseResult);
	}

	public static void addResultsToLog(StringBuffer vals) {

		File testCaseResFile = new File("EndtoendGroupsProfiles_result_"
				+ Configuration.getProperty("vmname") + ".txt");

		try {
			testCaseResFile.createNewFile();
			FileOutputStream fout = new FileOutputStream(testCaseResFile);

			//

			fout.write(vals.toString().getBytes());

			fout.flush();
			fout.close();

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	public static void pauseEndpoint(String eid) throws Exception {

		String pause = "{ " + "  \"type\":\"pause_many\", "
				+ "  \"endpoints\":[ " + "\"" + eid + "\" " + " ] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", pause);

	}

	public static void resumeEndpoint(String eid) throws Exception {

		String resume = "{ " + "  \"type\":\"resume_many\", "
				+ "  \"endpoints\":[ " + "    \"" + eid + "\" " + "] " + "} ";

		HttpClientUtils.composePostRequest(
				Configuration.getProperty("restapirooturi")
						+ "/endpoints/command", resume);

	}
	

}
